package com.xunji.user.service.impl;


import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xunji.user.entity.Org;
import com.xunji.user.mapper.OrgMapper;
import com.xunji.user.service.OrgService;
import com.xunji.user.vo.rep.OrgQueryResponse;
import com.xunji.user.vo.req.OrgAddRequest;
import com.xunji.user.vo.req.OrgUpdateRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrgServiceImpl extends ServiceImpl<OrgMapper, Org> implements OrgService {


    @Override
    public List<OrgQueryResponse> getOrgs() {
        List<OrgQueryResponse> orgQueryResponses = this.list().stream().map(OrgQueryResponse::getInstance).collect(Collectors.toList());

        // 添加机构人数
        doOrgCount(orgQueryResponses);

        return makePidTree(orgQueryResponses, 0);
    }

    private void doOrgCount(List<OrgQueryResponse> orgQueryResponses) {
        for (OrgQueryResponse orgQueryResponse : orgQueryResponses) {
            Integer orgId = orgQueryResponse.getId();
            ArrayList<Integer> userIds = getAllChildrenId(orgId);
            Long count = SpringUtil.getBean(UserServiceImpl.class).getUserCount(userIds);
            orgQueryResponse.setUserCount(count);
        }
    }

    @Override
    public List<Org> getByIds(List<Integer> ids) {
        QueryWrapper<Org> qw = new QueryWrapper<Org>().in("id", ids);
        return list(qw);
    }

    @Override
    public Org getOrgById(Integer id) {
        return getById(id);
    }

    @Override
    public Org selectById(Integer id) {
        return this.getById(id);
    }

    @Override
    public List<Org> selectByName(String name) {
        QueryWrapper<Org> qw = new QueryWrapper<Org>().eq(StringUtils.hasText(name), "name", name);
        return this.baseMapper.selectList(qw);
    }

    @Override
    public List<Org> selectByNameAndNotSelf(String name, Integer id) {
        QueryWrapper<Org> qw = new QueryWrapper<Org>().eq(StringUtils.hasText(name), "name", name).ne("id", id);
        return this.baseMapper.selectList(qw);
    }

    @Override
    public List<Org> selectByPid(Integer pid) {
        QueryWrapper<Org> qw = new QueryWrapper<Org>().eq("p_id", pid);
        return this.baseMapper.selectList(qw);
    }

    /**
     * 根据当前id，获取所有子节点id（包含自身）
     *
     * @param id
     * @return
     */
    @Override
    public ArrayList<Integer> getAllChildrenId(Integer id) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(id);
        getAllId(list, id); // 递归调用
        return list;
    }

    private void getAllId(ArrayList<Integer> list, Integer id) {
        List<Org> orgs = selectByPid(id);
        if (orgs != null && !orgs.isEmpty()) {
            for (Org org : orgs) {
                getAllId(list, org.getId());
                list.add(org.getId());
            }
        }
    }

    private List<OrgQueryResponse> makePidTree(List<OrgQueryResponse> orgQueryResponses, Integer pid) {
        List<OrgQueryResponse> children = orgQueryResponses.stream().filter(x -> x.getPId().equals(pid)).sorted(Comparator.comparing(OrgQueryResponse::getWeight)).collect(Collectors.toList());
        List<OrgQueryResponse> successor = orgQueryResponses.stream().filter(x -> !x.getPId().equals(pid)).collect(Collectors.toList());
        children.forEach(x -> {
            x.setChildren(makePidTree(successor, x.getId()));
        });
        return children;
    }

    @Override
    public void addOrg(OrgAddRequest request) {
        this.save(Org.getInstance(request));
    }

    @Override
    public void updateOrg(OrgUpdateRequest request) {
        this.updateById(Org.getInstance(request));
    }

    @Override
    public void deleteById(Integer id) {
        this.removeById(id);
    }
}
